﻿namespace TestProject
{
    using System;
    using System.IO;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Swiss;

    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class IniFile_Tests
    {
        public IniFile_Tests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region IniFile

        private static void Crud<T>(T value1, T value2)
        {
            using (IniFile ini = new IniFile("test.ini"))
            {
                ini.Clear();

                //Create
                ini.Write<T>("test", "value1", value1);
                ini.UpdateFile();

                Assert.IsTrue(ini.ValueExists("test", "value1"), "Value Not Found");

                //Read Existing
                Assert.IsTrue(ini.Read<T>("test", "value1", value1).Equals(value1), "Value Mismatch");

                //Read Non Existing
                Assert.IsFalse(ini.ValueExists("test", "value2"), "Value Found");
                Assert.IsTrue(ini.Read<T>("test", "value2", value2).Equals(value2), "Default Value Not Used");

                //Update
                ini.Write<T>("test", "value2", value2);
                Assert.IsTrue(ini.Read<T>("test", "value2", value2).Equals(value2), "Value Mismatch");
                ini.UpdateFile();

                //Delete Existing
                ini.DeleteKey("test", "value2");
                Assert.IsTrue(ini.Read<T>("test", "value2", value1).Equals(value1), "Value Mismatch");

                //Delete Non Existing
                ini.DeleteKey("test2", "value2");
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestAppDataPath()
        {
            IniFile ini = new IniFile("test.ini");

            Console.WriteLine(ini.FileName);

            Assert.AreNotEqual("test.ini", ini.FileName);
            Assert.AreNotEqual(Path.GetFullPath("test.ini"), ini.FileName);
        }

        [TestMethod]
        public void TestPathDotSlash()
        {
            IniFile ini = new IniFile(".\\test.ini");

            Console.WriteLine(ini.FileName);

            Assert.AreNotEqual("test.ini", ini.FileName);
            Assert.AreEqual(Path.GetFullPath(".\\test.ini"), ini.FileName);
        }

        [TestMethod]
        public void TestPathDotDotSlash()
        {
            IniFile ini = new IniFile("..\\test.ini");

            Console.WriteLine(ini.FileName);

            Assert.AreNotEqual("test.ini", ini.FileName);
            Assert.AreEqual(Path.GetFullPath("..\\test.ini"), ini.FileName);
        }

        [TestMethod]
        public void TestAppDataPathSave()
        {
            using (IniFile ini = new IniFile("test.ini"))
            {
                ini.UpdateFile();

                Assert.IsTrue(Directory.Exists(Path.GetDirectoryName(ini.FileName)), "Directory not found");
                Assert.IsTrue(File.Exists(ini.FileName), "IniFile not found");
            }
        }

        [TestMethod]
        public void TestRename()
        {
            using (IniFile ini = new IniFile("test.ini"))
            {
                ini.Write<String>("test", "value", "TheQuick", "Brown Fox");
                ini.UpdateFile();

                String path = ini.FileName;

                ini.Rename("test2.ini");

                Assert.IsTrue(Directory.Exists(Path.GetDirectoryName(ini.FileName)), "Directory not found");
                Assert.IsTrue(File.Exists(ini.FileName), "IniFile not found");
                Assert.IsFalse(File.Exists(path), "Old IniFile still present");
            }
        }

        [TestMethod]
        public void TestDirty()
        {
            using (IniFile ini = new IniFile("test.ini"))
            {
                ini.Clear();

                ini.UpdateFile();

                String path = ini.FileName;
                ini.WriteBool("test", "bool", true);
                Assert.IsTrue(ini.Dirty, "Not Dirty");
                ini.UpdateFile();
                Assert.IsFalse(ini.Dirty, "Still Dirty");
            }
        }

        [TestMethod]
        public void Test_CRUD_Bool()
        {
            Crud<Boolean>(true, false);
        }

        [TestMethod]
        public void Test_CRUD_Double()
        {
            Crud<double>(17.52, 15.3);
        }

        [TestMethod]
        public void Test_CRUD_Int32()
        {
            Crud<int>(17, 15);
        }

        [TestMethod]
        public void Test_CRUD_Byte()
        {
            Crud<Byte>(17, 15);
        }

        [TestMethod]
        public void Test_CRUD_String()
        {
            Crud<String>("The Quick Brown", "Fox");
        }

        [TestMethod]
        public void Test_CRUD_Date()
        {
            Crud<DateTime>(new DateTime(2007, 4, 27), new DateTime(2008, 5, 14));
        }

        [TestMethod]
        public void Test_CRUD_DateTime()
        {
            Crud<DateTime>(new DateTime(2007, 4, 27, 9, 15, 0), new DateTime(2008, 5, 14, 8, 45, 0));
        }

        [TestMethod]
        public void Test_CRUD_ByteStruct()
        {
            Crud<Byte[]>(new Byte[] { 10, 11, 12, 13 }, new Byte[] { 10, 11, 12, 15 });
        }

        [TestMethod]
        public void Test_CRUD_UInt16Struct()
        {
            Crud<UInt16[]>(new UInt16[] { 10, 11, 12, 13 }, new UInt16[] { 10, 11, 12, 15 });
        }

        [TestMethod]
        public void Test_CRUD_UInt32Struct()
        {
            Crud<UInt32[]>(new UInt32[] { 10, 11, 12, 13 }, new UInt32[] { 10, 11, 12, 15 });
        }

        [TestMethod]
        public void Test_CRUD_Time()
        {
            DateTime d1 = new DateTime(1, 1, 1);
            DateTime d2 = new DateTime(1, 1, 1);

            d1 = d1.AddHours(9);
            d1 = d1.AddMinutes(15);

            d2 = d2.AddHours(8);
            d2 = d2.AddMinutes(45);

            Crud<DateTime>(d1, d2);
        }

        [TestMethod]
        public void TestSection()
        {
            using (IniFile ini = new IniFile("test.ini"))
            {
                ini.EraseSection("test");

                //Create Section
                ini.WriteBool("test", "bool", true);

                Assert.IsTrue(ini.SectionExists("test"), "Section Not Found");
                Assert.IsFalse(ini.SectionExists("test2"), "Section Found");

                ini.EraseSection("test");
                Assert.IsFalse(ini.SectionExists("test"), "Section Found");

                ini.EraseSection("test2");

                ini.UpdateFile();
            }
        }

        [TestMethod]
        public void TestGeneric()
        {
            using (IniFile ini = new IniFile("test.ini"))
            {
                ini.EraseSection("test");

                //Create Section
                ini.Write<String>("test", "string", "a value");

                Assert.AreEqual("a value", ini.Read<String>("test", "string", "error"), "Value Mismatch");
                Assert.AreEqual("a value", ini.Read<string>("test", "string", "error"), "Value Mismatch");

                ini.Write<Int32>("test", "string", 27);
                Assert.AreEqual(27, ini.Read<Int32>("test", "string", 5), "Value Mismatch");
                Assert.AreEqual(27, ini.Read<int>("test", "string", 5), "Value Mismatch");

                Assert.AreEqual(27, ini.Read<Byte>("test", "string", 5), "Value Mismatch");

                ini.UpdateFile();
            }
        }

        #endregion IniFile

    }
}
